import asyncio
import logging
import os
from pathlib import Path

import httpx
from bilibili_api import HEADERS, Credential, video

from config import SESSDATA, BILI_JCT, BUVID3, FFMPEG_PATH, VIDEO_CACHE_PATH
from util import get_true_bv


async def download_url(url: str, out: Path, info: str):
    # 下载函数
    async with httpx.AsyncClient(headers=HEADERS) as sess:
        resp = await sess.get(url)
        length = resp.headers.get('content-length')
        with open(out, 'wb') as f:
            process = 0
            for chunk in resp.iter_bytes(1024):
                if not chunk:
                    break

                process += len(chunk)
                logging.debug(f'下载 {info} {process} / {length}')
                f.write(chunk)


async def download_bv(bv: str, index=0):
    # 实例化 Credential 类
    credential = Credential(sessdata=SESSDATA, bili_jct=BILI_JCT, buvid3=BUVID3)
    # 实例化 Video 类
    v = video.Video(bvid=bv, credential=credential)
    # 获取视频下载链接
    download_url_data = await v.get_download_url(index)
    # 解析视频下载信息
    detector = video.VideoDownloadURLDataDetecter(data=download_url_data)
    streams = detector.detect_best_streams()
    # 有 MP4 流 / FLV 流两种可能
    if index != 0:
        format_bv_path = VIDEO_CACHE_PATH / f"{bv}#{index}.mp4"
    else:
        format_bv_path = VIDEO_CACHE_PATH / f"{bv}.mp4"

    if format_bv_path.exists():
        try:
            os.remove(format_bv_path)
        except Exception as e:
            logging.exception(e)

    if detector.check_flv_stream():
        temp_bv_path = VIDEO_CACHE_PATH / f"{bv}.flv"
        # FLV 流下载
        await download_url(streams[0].url, temp_bv_path, "FLV 音视频流")
        # 转换文件格式
        os.system(f'{FFMPEG_PATH} -i {str(temp_bv_path.resolve())} {str(format_bv_path.resolve())}')
        # 删除临时文件
        os.remove(temp_bv_path)
    else:
        temp_bv_path_v = VIDEO_CACHE_PATH / f"{bv}_v.m4s"
        temp_bv_path_a = VIDEO_CACHE_PATH / f"{bv}_a.m4s"
        # MP4 流下载
        await download_url(streams[0].url, temp_bv_path_v, "视频流")
        await download_url(streams[1].url, temp_bv_path_a, "音频流")
        # 混流
        os.system(f'{FFMPEG_PATH} -i {str(temp_bv_path_v.resolve())} -i {str(temp_bv_path_a.resolve())} '
                  f'-vcodec copy -acodec copy {str(format_bv_path.resolve())}')
        # 删除临时文件
        os.remove(temp_bv_path_v)
        os.remove(temp_bv_path_a)


async def get_video_info(bv: str):
    v = video.Video(bvid=bv)
    info = await v.get_info()
    return info


if __name__ == '__main__':
    asyncio.run(get_video_info("BV1LS4y1b7Kq", 4))
